package OrderService

import (
	"context"
	"errors"
	"fmt"
	"gdshop-admin-go-api/app/entity"
	"gdshop-admin-go-api/app/request/OrderReq"
	"gdshop-admin-go-api/app/service/GoodsService"
	"gdshop-admin-go-api/app/service/MemberService"
	"gdshop-admin-go-api/library/event"
	"gdshop-admin-go-api/library/response"
	"gdshop-admin-go-api/library/tools"
	"gdshop-admin-go-api/library/tools/HttpQueue"
	toolsDb "gdshop-admin-go-api/library/tools/db"
	"gdshop-admin-go-api/library/tools/wxpayHelper"
	"github.com/gogf/gf/container/garray"
	"github.com/gogf/gf/database/gdb"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/text/gstr"
	"github.com/gogf/gf/util/gconv"
	"github.com/shenghui0779/gochat/mch"
	"time"
)

func checkChangeOrderStatusData(ctx context.Context, orderModel *entity.Order, typeStr string,
	params *OrderReq.ChangeStatus) error {
	allowTypes := []string{
		"send_express",
		"cancel_express",
		"close_order",
		"back_pay",
		"member_pay",
		"confirm_goods",
		"cancel_goods",
		"confirm_order",
		"evaluated",
	}

	statusAllowTypes := map[int][]string{
		1: {
			"back_pay",
			"close_order",
			"member_pay",
		},
		2: {
			"confirm_goods",
			"close_order",
		},
		3: {
			"cancel_goods",
			"send_express",
			"cancel_express",
			"close_order",
		},
		4: {
			"cancel_express",
			"confirm_order",
		},
		5: {
			"evaluated",
		},
	}
	statusErrors := map[int]string{
		0:  "关闭订单和完成订单后，不允许再改变状态",
		1:  "待付款，只能关闭和付款",
		2:  "待备货，只能备货和关闭订单",
		3:  "待发货，只能发货、取消发货、取消备货和关闭订单",
		4:  "待收货，只能取消发货和确认收货",
		5:  "待评价，只能评价",
		99: "关闭订单和完成订单后，不允许再改变状态",
	}

	if !gstr.InArray(allowTypes, typeStr) {
		return errors.New("不允许的类型")
	}

	// 判断订单在某些状态下不可跨状态设置
	if orderModel.Status == 0 || orderModel.Status == 99 {
		// 关闭订单和完成订单后，不允许再改变状态
		return errors.New(statusErrors[orderModel.Status])
	}

	if !gstr.InArray(statusAllowTypes[orderModel.Status], typeStr) {
		return errors.New(statusErrors[orderModel.Status])
	}

	/*
		// 待付款，只能关闭和后台付款、会员付款
		if orderModel.Status == 1 {
			if !(typeStr == "back_pay" || typeStr == "close_order" || typeStr == "member_pay") {
				return errors.New("待付款，只能关闭和付款")
			}
		}

		// 待备货，只能备货和关闭订单
		if orderModel.Status == 2 {
			if !(typeStr == "confirm_goods" || typeStr == "close_order") {
				return errors.New("待备货，只能备货和关闭订单")
			}
		}

		// 待发货，只能发货、取消发货、取消备货和关闭订单
		if orderModel.Status == 3 {
			if !(typeStr == "cancel_goods" || typeStr == "send_express" || typeStr == "cancel_express" || typeStr == "close_order") {
				return errors.New("待发货，只能发货、取消发货、取消备货和关闭订单")
			}
		}
		// 待收货，只能取消发货和确认收货
		if orderModel.Status == 4 {
			if !(typeStr == "cancel_express" || typeStr == "confirm_order") {
				return errors.New("待收货，只能取消发货和确认收货")
			}
		}
		// 待评价，只能评价
		if orderModel.Status == 5 {
			if !(typeStr == "evaluated") {
				return errors.New("待评价，只能评价")
			}
		}
	*/
	if typeStr == "cancel_goods" {
		osCount, err := toolsDb.GetUnSafaTable(ctx, "order_sub").Where(
			"status = 4 AND order_id = ?",
			gconv.SliceAny(params.OrderId),
		).Count()
		if err != nil {
			return err
		}
		if osCount > 0 {
			return errors.New("已有部分子订单发货，不允许取消备货")
		}
	}

	if typeStr == "send_express" {
		// 发货，必须存在发货信息
		if params.ExpressId == 0 {
			return errors.New("请选择快递公司")
		}
		if len(params.ExpressSn) < 1 {
			return errors.New("请输入运单号")
		}

		// 判断快递公司是否存在
		count, err := toolsDb.GetUnSafaTable(ctx, "express").Where("id", params.ExpressId).Count()
		if err != nil {
			return err
		}
		if count < 1 {
			return errors.New("快递公司数据错误")
		}

		if params.IsSplit > 0 {
			// 分批发货
			if len(params.OrderSubIds) < 1 {
				return errors.New("分批发货，请选择子订单")
			}
			// 查询子订单是否存在
			osCount, err := toolsDb.GetUnSafaTable(ctx, "order_sub").Where("status = 3 AND id IN (?)",
				gconv.SliceAny(params.OrderSubIds),
			).Count()
			if err != nil {
				return err
			}
			if len(params.OrderSubIds) != osCount {
				return errors.New("分批发货，子订单不一致，请刷新页面重试")
			}
		}
	}

	if typeStr == "cancel_express" {
		// 取消发货，必须存在子订单信息
		if len(params.OrderSubIds) > 0 {
			osCount, err := toolsDb.GetUnSafaTable(ctx, "order_sub").Where("status = 4 AND id IN (?)",
				gconv.SliceAny(params.OrderSubIds)).Count()
			if err != nil {
				return err
			}
			if len(params.OrderSubIds) != osCount {
				return errors.New("分批发货，子订单不一致，请刷新页面重试")
			}
		}
	}

	if typeStr == "close_order" {
		// 关闭订单时，必须保证子订单没有退款状态
		if params.OrderId < 1 {
			return errors.New("order_id 不能为空")
		}
		osCount, err := toolsDb.GetUnSafaTable(ctx, "order_sub").Where(
			"status > 3 AND order_id = ?",
			params.OrderId).Count()
		if err != nil {
			return err
		}
		if osCount > 0 {
			return errors.New("有子订单已经发货请先取消子订单发货")
		}
		osCount, err = toolsDb.GetUnSafaTable(ctx, "order_sub").Where(
			"refund_status > 0 AND refund_status < 99 AND order_id = ?",
			params.OrderId).Count()
		if err != nil {
			return err
		}
		if osCount > 0 {
			return errors.New("有子订单有售后状态，请到售后处理")
		}
	}

	if typeStr == "member_pay" {
		// 余额支付，判断会员是否有足够的余额
		if params.Payment == "balance" {
			var memberModel *entity.Member
			err := toolsDb.GetUnSafaTableAddDeleteWhere(ctx, "member").Where("id",
				params.MemberId).Struct(&memberModel)
			if err != nil {
				return errors.New("查询会员余额失败：" + err.Error())
			}

			if orderModel.TotalPrice > memberModel.MoneyCoin {
				return errors.New("余额不足")
			}
		}
	}

	return nil
}

func ChangeStatus(ctx context.Context, params *OrderReq.ChangeStatus) *response.JsonResponse {
	orderModel := getOrderModel(ctx, params.OrderId)
	if orderModel == nil {
		return response.FailByRequestMessage(nil, "找不到订单")
	}

	err := checkChangeOrderStatusData(ctx, orderModel, params.Type, params)
	if err != nil {
		return response.FailByRequestMessage(nil, err.Error())
	}

	err = orderIsOption(orderModel, params.Type)
	if err != nil {
		return response.FailByRequestMessage(nil, err.Error())
	}

	if params.Type == "send_express" || params.Type == "cancel_express" {
		return handleChangeOrderStatusLogExpress(ctx, orderModel, params)
	}

	return handleChangeOrderStatusLogNormal(ctx, orderModel, params)
}

// 处理订单变更 - 物流 类型 send_express、cancel_express
func handleChangeOrderStatusLogExpress(ctx context.Context, orderModel *entity.Order, params *OrderReq.ChangeStatus) *response.JsonResponse {
	if params.Type != "send_express" && params.Type != "cancel_express" {
		return response.FailByRequestMessage(nil, "不支持的 type")
	}
	var subList []*entity.OrderSub
	err := toolsDb.GetUnSafaTable(ctx, "order_sub").Where("order_id",
		params.OrderId).Structs(&subList)
	if err != nil {
		return response.FailByRequestMessage(nil, err.Error())
	}
	nowStatus := 0
	nowCount := 0
	nowTime := time.Now()
	newDatas := g.Map{}
	if params.Type == "send_express" {
		sendStatus := 4
		sendCount := 0

		var expressModel *entity.Express
		err := toolsDb.GetUnSafaTable(ctx, "express").Where("id",
			params.ExpressId).Struct(&expressModel)
		if err != nil {
			return response.FailByRequestMessage(nil, err.Error())
		}

		var tmpOrderExpress []*entity.OrderExpress
		tmpOrderSub := g.List{}
		if params.IsSplit == 0 {
			// 整单发货
			tmpOrderExpress = append(tmpOrderExpress, &entity.OrderExpress{
				OrderId:    params.OrderId,
				ExpressCom: expressModel.Name,
				Express:    expressModel.Express,
				ExpressSn:  params.ExpressSn,
				CreateAt:   nowTime.Unix(),
			})

			// 修改全部子订单状态
			// 整单发货，$data['order_sub_ids'] 写入全部ids
			tmpIds := []int{}
			for _, item := range subList {
				tmpIds = append(tmpIds, item.Id)
				tmpOrderSub = append(tmpOrderSub, g.Map{
					"id":     item.Id,
					"status": sendStatus,
				})
				sendCount++
			}
			params.OrderSubIds = tmpIds
		} else {
			// 分批发货，循环全部子订单
			for _, item := range params.OrderSubIds {
				tmpOrderExpress = append(tmpOrderExpress, &entity.OrderExpress{
					OrderSubId: item,
					ExpressCom: expressModel.Name,
					Express:    expressModel.Express,
					ExpressSn:  params.ExpressSn,
					CreateAt:   nowTime.Unix(),
				})

				tmpOrderSub = append(tmpOrderSub, g.Map{
					"id":     item,
					"status": sendStatus,
				})
				sendCount++
			}
		}

		nowStatus = sendStatus
		nowCount = sendCount

		// 如果计算出的个数和全部子订单一样，则说明要修改子订单
		// 计算子订单是否全部已经发货，或者取消发货，如果是，更改主订单状态
		for _, item := range subList {
			// 子订单已经发货，并且不在刚才提交的子订单里面的
			if item.Status == 4 && (!tools.InArrayInt(item.Id, params.OrderSubIds)) {
				nowCount++
			}
		}
		tmpOrder := g.Map{}
		if nowCount >= len(subList) {
			tmpOrder["status"] = nowStatus
		}
		tmpOrder["is_split"] = params.IsSplit
		newDatas["Order"] = tmpOrder
		// ---------- 主订单状态计算完毕 ---------------------------

		newDatas["OrderExpress"] = tmpOrderExpress
		newDatas["OrderSub"] = tmpOrderSub
	}

	if params.Type == "cancel_express" {
		cancelStatus := 3
		cancelCount := 0

		var tmpOrderExpress []*entity.OrderExpress
		tmpOrderSub := g.List{}
		if params.IsSplit != 1 {
			// 整单取消发货，$data['order_sub_ids'] 写入全部ids
			tmpIds := []int{}
			for _, item := range subList {
				tmpIds = append(tmpIds, item.Id)
				tmpOrderSub = append(tmpOrderSub, g.Map{
					"id":     item.Id,
					"status": cancelStatus,
				})
				cancelCount++
			}
			params.OrderSubIds = tmpIds
		} else {
			// 分批取消
			for _, item := range params.OrderSubIds {
				tmpOrderExpress = append(tmpOrderExpress, &entity.OrderExpress{
					DeleteAt: nowTime.Unix(),
				})

				tmpOrderSub = append(tmpOrderSub, g.Map{
					"id":     item,
					"status": cancelStatus,
				})
				cancelCount++
			}
		}
		nowStatus = cancelStatus
		nowCount = cancelCount

		tmpOrder := g.Map{}
		// 计算主订单状态
		// 不分批发货，order_sub_ids 为空，说明是整单操作
		if params.IsSplit == 0 {
			tmpOrder = g.Map{
				"is_split": params.IsSplit,
				"status":   nowStatus,
			}
			tmpOrderExpress = append(tmpOrderExpress, &entity.OrderExpress{
				DeleteAt: nowTime.Unix(),
			})
			tmpOrderSub = append(tmpOrderSub, g.Map{
				"status": nowStatus,
			})
		} else {
			for _, item := range subList {
				if item.Status == 4 && (!tools.InArrayInt(item.Id, params.OrderSubIds)) {
					nowCount++
				}
			}
			if nowCount >= len(subList) {
				tmpOrder = g.Map{
					"status":   nowStatus,
					"is_split": params.IsSplit,
				}
			}
		}

		newDatas["OrderExpressMofdiy"] = tmpOrderExpress
		newDatas["OrderSub"] = tmpOrderSub
		newDatas["Order"] = tmpOrder
	}

	oldData := g.Map{
		"status": orderModel.Status,
	}

	err = g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
		// 循环更新
		for key, item := range newDatas {
			switch key {
			case "OrderExpressMofdiy":
				whereMap := g.Map{}
				if params.IsSplit > 0 {
					// 分批发货
					whereMap["order_sub_id IN (?)"] = gconv.SliceAny(params.OrderSubIds)
				} else {
					whereMap["order_id"] = params.OrderId
				}
				_, err := tx.Model("order_express").Where(whereMap).Update(g.Map{
					"delete_at": nowTime.Unix(),
				})
				if err != nil {
					return err
				}
				break
			case "OrderExpress":
				_, err := tx.Model("order_express").Insert(item)
				if err != nil {
					return err
				}
				break
			case "OrderSub":
				_, err := tx.Model("order_sub").Where("id IN (?)", gconv.SliceAny(params.OrderSubIds)).Update(g.Map{
					"status": nowStatus,
				})
				if err != nil {
					return err
				}
				break
			case "Order":
				tmp := gconv.Map(item)
				if len(tmp) < 1 {
					continue
				}
				_, err := tx.Model("order").Where("id", orderModel.Id).Update(item)
				if err != nil {
					return err
				}
				break
			}
		}

		// 处理日志
		_, err := tx.Model("order_log").InsertAndGetId(g.Map{
			"type":      params.Type,
			"order_id":  orderModel.Id,
			"admin_id":  params.AdminId,
			"old_data":  oldData,
			"new_data":  newDatas,
			"create_at": nowTime.Unix(),
		})
		if err != nil {
			return err
		}

		return nil
	})

	if err != nil {
		return response.FailByRequestMessage(nil, err.Error())
	}

	// 发货后，加入队列，到时间自动转换成为待评价状态
	if params.Type == "send_express" {
		// 全部子订单已经改变状态，并且状态为 4 待收货
		if nowCount >= len(subList) && nowStatus == 4 {
			HttpQueue.AddCompleteOrder(params.OrderId)
		}
	}

	return response.SuccessByRequestMessage(nil, "成功")
}

func getPaymentMethodInt(ctx context.Context, paymentCode string) int {
	value, err := toolsDb.GetUnSafaTableAddDeleteWhere(ctx, "payments").Where(
		"code=?",
		paymentCode,
	).Fields("id").Cache(600 * time.Second).Value()
	if err != nil {
		return 0
	}
	return value.Int()
}

// 处理普通订单变更，类型 close_order、back_pay、confirm_goods、cancel_goods、confirm_order
func handleChangeOrderStatusLogNormal(ctx context.Context, orderModel *entity.Order, params *OrderReq.ChangeStatus) *response.JsonResponse {
	allowTypes := g.MapStrInt{
		"close_order":   0,  // 关闭订单
		"back_pay":      2,  // 后台付款
		"member_pay":    2,  // 会员付款
		"confirm_goods": 3,  // 备货
		"cancel_goods":  2,  // 取消备货
		"confirm_order": 5,  // 确认收货
		"evaluated":     99, // 评价后，订单完成
	}
	newData := g.Map{
		"status": allowTypes[params.Type],
	}
	if params.Remark != "" {
		newData["remark"] = params.Remark
	}
	oldData := g.Map{
		"status": orderModel.Status,
	}

	err := g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
		_, err := tx.Model("order").Where("id", orderModel.Id).Update(newData)
		if err != nil {
			return err
		}
		// back_pay 还需要写后台支付日志，写入付款信息
		if params.Type == "back_pay" {
			_, err := tx.Model("order_back_pay_log").InsertAndGetId(g.Map{
				"order_id":  orderModel.Id,
				"admin_id":  params.AdminId,
				"money":     orderModel.TotalPrice,
				"create_at": time.Now().Unix(),
			})
			if err != nil {
				return err
			}
			_, err = tx.Model("order_pay_log").InsertAndGetId(g.Map{
				"order_id":       orderModel.Id,
				"pay_log_id":     0,
				"payment_method": getPaymentMethodInt(ctx, params.Type),
				"money":          orderModel.TotalPrice,
				"create_at":      time.Now().Unix(),
			})
			if err != nil {
				return err
			}
		}

		if params.Type == "member_pay" {
			_, err = tx.Model("order_pay_log").InsertAndGetId(g.Map{
				"order_id":       orderModel.Id,
				"pay_log_id":     params.PayLogId,
				"payment_method": getPaymentMethodInt(ctx, params.Payment),
				"money":          orderModel.TotalPrice,
				"create_at":      time.Now().Unix(),
			})
			if err != nil {
				return err
			}

			if params.Payment == "balance" {
				// 如果是会员余额付款的话，扣款
				err := memberOrderCoinChange(tx, "-", "money_coin", orderModel.MemberId, orderModel.Id,
					int(orderModel.TotalPrice), "支付订单："+orderModel.OrderNo, params.AdminId, params.MemberId)
				if err != nil {
					return err
				}
			}
		}

		// 关闭订单，需要返回已支付的金额
		if params.Type == "close_order" {
			// 处理支付返回
			// 如果 status 大于 1 说明已经付款了，才处理退款
			if orderModel.Status > 1 {
				err = backOrderAllPriceTx(tx, orderModel, params.AdminId, params.MemberId)
				if err != nil {
					return err
				}
			}
			// 处理库存
			err = BackGoodsStock(tx, orderModel)
			if err != nil {
				return err
			}
		}

		// 更新子订单状态
		_, err = tx.Model("order_sub").Where("order_id", orderModel.Id).Update(g.Map{
			"status": allowTypes[params.Type],
		})
		if err != nil {
			return err
		}
		err = InsertOrderLog(tx, g.Map{
			"type":      params.Type,
			"order_id":  params.OrderId,
			"admin_id":  params.AdminId,
			"member_id": params.MemberId,
			"old_data":  oldData,
			"new_data":  newData,
		})
		if err != nil {
			return err
		}

		return nil
	})

	if err != nil {
		return response.FailByRequestMessage(nil, err.Error())
	}

	// 触发 事件
	TriggerOrderEvent(event.M{
		"type":      params.Type,
		"order_id":  params.OrderId,
		"payment":   params.Payment,
		"member_id": params.MemberId,
		"admin_id":  params.AdminId,
	})

	return response.SuccessByRequestMessage(nil, "成功")
}

func InsertOrderLog(tx *gdb.TX, data g.Map) error {
	data["create_at"] = time.Now().Unix()
	_, err := tx.Model("order_log").InsertAndGetId(data)
	if err != nil {
		return err
	}

	return nil
}

// 退还订单全部已支付金额
func backOrderAllPriceTx(tx *gdb.TX, orderModel *entity.Order, opAdminId, opMemberId int) error {
	/*var oplList []*entity.OrderPayLog
	err := tx.Model("order_pay_log").Where("order_id", orderModel.Id).Structs(&oplList)
	if err != nil {
		return err
	}
	for _, item := range oplList {
		err := BackOrderPayLogPriceTx(tx, orderModel.MemberId, orderModel.Id, gconv.Int(item.Money),
			item.PaymentMethod, "关闭订单："+orderModel.OrderNo, opAdminId, opMemberId)
		if err != nil {
			return err
		}
	}
	*/
	return OrderBackPriceTx(tx, orderModel.Id, orderModel.TotalPrice, orderModel.MemberId, opAdminId, opMemberId,
		"关闭订单："+orderModel.OrderNo)
}

// OrderBackPriceTx 退款
// orderId 退款订单ID
// backPrice 退款金额
// byMemberId 给谁退款
// opAdminId 操作管理ID
// opMemberId 操作会员ID
// remark 退款备注
func OrderBackPriceTx(tx *gdb.TX, orderId int, backPrice int64, byMemberId, opAdminId, opMemberId int,
	remark string) error {

	var oplList []*entity.OrderPayLog
	err := tx.Model("order_pay_log").Where(
		"order_id = ? AND money > refund_fee",
		orderId).Fields("*,(money - refund_fee) AS refundable").Structs(&oplList)
	if err != nil {
		return err
	}
	var tmpMoney int64
	// 应退金额
	mustBackMoney := backPrice
	for _, item := range oplList {
		// 应退金额小于，说明退完了
		if mustBackMoney < 1 {
			break
		}
		// 应退 金额 大于等于 可退
		if mustBackMoney >= item.Refundable {
			tmpMoney = item.Refundable
		} else {
			// 应退金额 不足当前
			tmpMoney = mustBackMoney
		}
		// ApplyId 只有申请人才能操作自己的订单
		err := BackOrderPayLogPriceTx(tx, byMemberId, orderId, gconv.Int(tmpMoney), item, remark,
			opAdminId, opMemberId)
		if err != nil {
			return err
		}
		// 退款成功，已退加上退款成功金额
		mustBackMoney -= tmpMoney
		// 写入 order_pay_log 已退金额 refund_fee
		update, err := tx.Model("order_pay_log").Unscoped().
			Where("id = ? AND (money - refund_fee) >= ?", item.Id, tmpMoney).Update(g.Map{
			"refund_fee": gdb.Raw("refund_fee+" + gconv.String(tmpMoney)),
		})
		if err != nil {
			return err
		}
		affected, err := update.RowsAffected()
		if err != nil {
			return err
		}
		if affected < 1 {
			return errors.New(fmt.Sprint("order_pay_log表更新refund_fee失败，ID：", item.Id))
		}
	}
	// 还有未退完的金额
	if mustBackMoney > 1 {
		return errors.New("退款失败")
	}

	return nil
}

// BackOrderPayLogPriceTx 退款
// oplItem order_pay_log表的一条记录
func BackOrderPayLogPriceTx(tx *gdb.TX, memberId, orderId, totalPrice int, oplItem *entity.OrderPayLog, remark string,
	opAdminId, opMemberId int) error {
	if oplItem.PaymentMethod == 1 {
		// 1余额支付
		err := memberOrderCoinChange(tx, "+", "money_coin",
			memberId, orderId, totalPrice, remark, opAdminId, opMemberId)
		if err != nil {
			return err
		}
	}
	if oplItem.PaymentMethod == 3 {
		// 3微信支付
		err := BackInWechatPay(tx, gconv.String(orderId), totalPrice, opAdminId, opMemberId, oplItem)
		if err != nil {
			return err
		}
	}
	if oplItem.PaymentMethod == 4 {
		// TODO: 待开发 4支付宝支付
		return errors.New("支付宝退款，开发中")
	}
	return nil
}

// plusOrreduce + 或者 -
func memberOrderCoinChange(tx *gdb.TX, plusOrreduce, typeStr string, memberId, orderId, totalPrice int, remark string,
	opAdminId, opMemberId int) error {
	/*allowType := []string{
		"integral_coin",
		"money_coin",
	}
	if !gstr.InArray(allowType, typeStr) {
		return errors.New("不支持" + typeStr + " 可用值:" + strings.Join(allowType, ","))
	}
	allowFuhao := []string{
		"+",
		"-",
	}
	if !gstr.InArray(allowFuhao, plusOrreduce) {
		return errors.New("不支持" + plusOrreduce + " 可用值:" + strings.Join(allowFuhao, ","))
	}
	// 如果是会员余额付款的话，扣款
	_, err := tx.Model("member").Where("id",
		memberId).Update(g.Map{
		typeStr: gdb.Raw(typeStr + plusOrreduce + gconv.String(totalPrice)),
	})
	if err != nil {
		return err
	}
	// 写会员日志
	_, err = tx.Model("member_finance").Insert(g.Map{
		"member_id":    memberId,
		"type_name":    typeStr,
		"coin":         plusOrreduce + gconv.String(totalPrice),
		"src_type":     "order",
		"src_id":       orderId,
		"op_member_id": opMemberId,
		"op_admin_id":  opAdminId,
		"create_time":  time.Now().Unix(),
		"remark":       remark,
	})
	if err != nil {
		return err
	}

	return nil*/

	return MemberService.CoinChange(tx, plusOrreduce, typeStr, "order", memberId, orderId, totalPrice, remark,
		opAdminId, opMemberId)
}

// 处理商品库存退还的问题
func BackGoodsStock(tx *gdb.TX, orderModel *entity.Order) error {
	var osList []*entity.OrderSub
	err := tx.Model("order_sub").Where("order_id", orderModel.Id).Structs(&osList)
	if err != nil {
		return err
	}
	goodsIds := garray.NewIntArray(true)
	for _, item := range osList {
		// 更新 商品规格表
		update, err := tx.Model("goods_option").Unscoped().Where("id", item.GoodsOptionId).Update(g.Map{
			"stock": gdb.Raw("stock+" + gconv.String(item.Total)),
		})
		if err != nil {
			return err
		}
		affected, err := update.RowsAffected()
		if err != nil {
			return err
		}
		if affected < 1 {
			g.Log().Cat("ChangeStatus").Async().Error("退还库存失败 order_subData:", item)
			return errors.New("退还库存失败")
		}

		if !goodsIds.Contains(item.GoodsId) {
			goodsIds.Append(item.GoodsId)
		}
	}
	for _, goodsId := range goodsIds.Slice() {
		// 更新总库存
		err := GoodsService.GoodsChangeRelated(tx, "stock", goodsId)
		if err != nil {
			return err
		}
	}

	return nil
}

// BackInWechatPay 微信退款
// orderId=订单号
// refundFee=退款金额
// opAdminId=操作管理员ID
// opMemberId=操作会员ID
// payLogId=pay_log表ID
func BackInWechatPay(tx *gdb.TX, orderId string, refundFee, opAdminId, opMemberId int, oplItem *entity.OrderPayLog) error {
	var plModel *entity.PayLog
	err := tx.Model("pay_log").Where(
		"payment_method = 1 AND status = 1 AND id = ?",
		oplItem.PayLogId).Scan(&plModel)
	if err != nil {
		panic(err)
	}
	if plModel == nil {
		return errors.New("找不到支付信息")
	}
	if refundFee > plModel.Money {
		return errors.New("退款金额不能大于支付金额")
	}
	wxpay := wxpayHelper.GetWxpay(true)
	data := mch.RefundData{
		OutRefundNO: orderId + "R" + gconv.String(tools.MakeTimestamp()),
		TotalFee:    plModel.Money,
		RefundFee:   refundFee,
		NotifyURL:   g.Cfg().GetString("pay.wechatpay.refundNotifyURL"),
	}
	do, err := wxpay.Do(context.Background(), mch.RefundByOutTradeNO(plModel.OrderId, &data))
	if err != nil {
		panic(err)
	}
	if do["result_code"] != "SUCCESS" {
		return errors.New("退款发起失败 code: " + do["err_code"] + " des:" + do["err_code_des"])
	}
	// 写入 pay_refund
	_, err = tx.Model("pay_refund").Unscoped().InsertAndGetId(g.Map{
		"order_id":       orderId,
		"pay_log_id":     oplItem.PayLogId,
		"refund_no":      data.OutRefundNO,
		"payment_method": 1, // 微信支付的，所以写死
		"total_fee":      plModel.Money,
		"refund_fee":     refundFee,
		"admin_id":       opAdminId,
		"member_id":      opMemberId,
	})
	if err != nil {
		return err
	}

	return nil
}
